﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JCTimes.DomainModel.Repository;
using JCTimes.DomainModel.Views;
using JCTimes.DomainModel.Entity;
using JCTimes.Portal.Infrastructure;
using JCTimes.Portal.Models;
using JCTimes.Portal.Specification;
using System.Data;


namespace JCTimes.Portal.Controllers
{
     [Permission]
    public class PDAController : Controller
    {
        //
        // GET: /PDA/

        private IPDARepository dmRep = null;
        private IPDAFunctionsRepository pfunRep = null;
        private IPDAUsersFunctionsRepository pufunRep = null;
        private IPDAPDAFunctionsRepository ppfunRep = null;

        private const int pageSize = 10;

        public PDAController(IPDARepository dmRep, IPDAFunctionsRepository pfunRep,IPDAUsersFunctionsRepository pufunRep,IPDAPDAFunctionsRepository ppfunRep)
        {
            this.dmRep = dmRep;
            this.pfunRep = pfunRep;
            this.pufunRep = pufunRep;
            this.ppfunRep = ppfunRep;
        }

        public ActionResult Index(string accountid)
        {
            if (!string.IsNullOrEmpty(accountid))
            {
                TempData["accountid"] = accountid;
            }
            else
            {
                TempData["accountid"] = null;
            }
            return View();
        }

        /// <summary>
        /// Query users.
        /// </summary>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter conditions.</param>
        /// <returns>Users grid view</returns>
        public PartialViewResult Grid(int? pageIndex, Searcher searcher)
        {
            UserInfo uinfo = SessionHelper.CurrUser;
            string accountid = "";
            if (TempData.Peek("accountid") != null)
            {
                accountid = TempData.Peek("accountid").ToString().Trim() ?? "";
            }

            var pred = PDASpecification.Get_V_PDA_Pred(searcher);
            if (accountid != "")
            {
                var model = new GridView<V_PDA>
                {
                    Searcher = searcher,
                    PagedList = dmRep.GetList<V_PDA>().Where(pred).Where(m=>m.UsersID==accountid).OrderByDescending(u => u.CreateDate).ToPagedList(pageIndex ?? 1, pageSize)
                };
                return PartialView("_gridview", model);
            }
            else
            {
                if (uinfo.RoleID == Constant.Admin)
                {
                    var model = new GridView<V_PDA>
                    {
                        Searcher = searcher,
                        PagedList = dmRep.GetList<V_PDA>().Where(pred).OrderByDescending(u => u.CreateDate).ToPagedList(pageIndex ?? 1, pageSize)
                    };
                    return PartialView("_gridview", model);
                }
                else if (uinfo.RoleID == Constant.Agency)
                {
                    var model = new GridView<V_PDA>
                    {
                        Searcher = searcher,
                        PagedList = dmRep.GetList<V_PDA>().Where(pred).Where(m=>m.CreateUsersID==uinfo.UserID).OrderByDescending(u => u.CreateDate).ToPagedList(pageIndex ?? 1, pageSize)
                    };
                    return PartialView("_gridview", model);
                }
                else
                {
                    var model = new GridView<V_PDA>
                    {
                        Searcher = searcher,
                        PagedList = dmRep.GetList<V_PDA>().Where(pred).Where(m => m.UsersID == uinfo.UserID).OrderByDescending(u => u.CreateDate).ToPagedList(pageIndex ?? 1, pageSize)
                    };
                    return PartialView("_gridview", model);
                }
            }
        }

        public ActionResult Create()
        {
            return View(new PDA { ID = Guid.NewGuid().ToString() });
        }

        /// <summary>
        /// Edit user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter condtions.</param>
        /// <returns>User form.</returns>
        public ActionResult Edit(string id, int pageIndex, Searcher searcher)
        {
            TempData["pageIndex"] = pageIndex;
            TempData["searcher"] = searcher;
            return View(dmRep.Find(id));
        }

        /// <summary>
        /// Edit user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="forms">Form collections about user item.</param>
        /// <returns>Edit result, if success then redirect to list, else show validation errors.</returns>
        [HttpPost]
        public ActionResult Edit(string id, FormCollection forms)
        {
            var model = dmRep.Find(id);
            if (TryUpdateModel(model))
            {
                try
                {
                    dmRep.SaveChanges();
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(ex.Message, ex);
                }
                return RedirectToAction("Index");
            }
            return View(model);
        }

        public ActionResult FunctionCreate()
        {
            return View(new PDAFunction { ID = Guid.NewGuid().ToString() });
        }

        public ActionResult FunctionIndex()
        {
            return View();
        }

        public ActionResult FunctionTree()
        {
            var funcs = pfunRep.All.OrderBy(f => f.OrderID).ToList(); //系统所有功能
            string[] filters = new string[] {
                "ID", "FunctionNo","FunctionName", "ParentID", "OrderID"};

            var dt = funcs.ToDataTable(filters);
            TreeView tree = new TreeView();
            ViewData["TreeView"] = tree.CreateTree(dt, 0);

            return View();
        }

        /// <summary>
        /// Edit user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter condtions.</param>
        /// <returns>User form.</returns>
        public ActionResult FunctionEdit(string id, int pageIndex, Searcher searcher)
        {
            TempData["pageIndex"] = pageIndex;
            TempData["searcher"] = searcher;
            return View(pfunRep.Find(id));
        }

        /// <summary>
        /// Delete user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter conditions</param>
        /// <returns></returns>
        public RedirectToRouteResult FunctionDelete(string id, int pageIndex, Searcher searcher)
        {
            try
            {
                var user = pfunRep.Find(id);
                pfunRep.Delete(user);
                pfunRep.SaveChanges();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex.Message, ex);
            }
            return RedirectToAction("FunctionGrid", new { pageIndex = pageIndex, searcher = searcher });
        }

        /// <summary>
        /// Edit user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="forms">Form collections about user item.</param>
        /// <returns>Edit result, if success then redirect to list, else show validation errors.</returns>
        [HttpPost]
        public ActionResult FunctionEdit(string id, FormCollection forms)
        {
            var model = pfunRep.Find(id);
            if (TryUpdateModel(model))
            {
                try
                {
                    pfunRep.SaveChanges();
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(ex.Message, ex);
                }
                return RedirectToAction("FunctionIndex");
            }
            return View(model);
        }

        /// <summary>
        /// Query users.
        /// </summary>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter conditions.</param>
        /// <returns>Users grid view</returns>
        public PartialViewResult FunctionGrid(int? pageIndex, Searcher searcher)
        {
            var pred = PDAFunctionsSpecification.Get_V_PDAFunctions_Pred(searcher);
            var model = new GridView<V_PDAFunctions>
            {
                Searcher = searcher,
                PagedList = dmRep.GetList<V_PDAFunctions>().Where(pred).OrderByDescending(u => u.CreateDate).ToPagedList(pageIndex ?? 1, pageSize)
            };
            return PartialView("_functiongridview", model);
        }

        /// <summary>
        /// Add user.
        /// </summary>
        /// <param name="user">User item</param>
        /// <returns>Add result in json</returns>
        [HttpPost]
        public JsonResult Create(string UsersID, string CreateUsersID, string[] PDANo, string[] Purpose)
        {
            UserInfo uinfo = SessionHelper.CurrUser;
            if (string.IsNullOrEmpty(CreateUsersID))
            {
                CreateUsersID = uinfo.UserID;
            }
            for(int i=0;i<PDANo.Length;i++)
            {
                if (!string.IsNullOrEmpty(PDANo[i]))
                {
                    if (dmRep.Find(u => u.PDANo == PDANo[i]) != null)
                    {

                    }
                    else
                    {
                        PDA pinfo = new PDA();
                        pinfo.ID = Guid.NewGuid().ToString();
                        pinfo.UsersID = UsersID;
                        pinfo.CreateUsersID = CreateUsersID;
                        pinfo.CreateDate = System.DateTime.Now;
                        pinfo.PDANo = PDANo[i];
                        pinfo.Purpose = Purpose[i];
                        pinfo.Status = 0;
                        dmRep.Add(pinfo);
                    }
                }
            }
            try
            {
                dmRep.SaveChanges();
                return Json(new { Msg = "添加成功", IsSuccess = true });
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex.Message, ex);
                return Json(new { Msg = "出错了" });
            }
        }

        /// <summary>
        /// Add user.
        /// </summary>
        /// <param name="user">User item</param>
        /// <returns>Add result in json</returns>
        [HttpPost]
        public JsonResult FunctionCreate(PDAFunction pdafunction)
        {
            //生成PDA功能编号
            string parentid = pdafunction.ParentID;
            //得到对应上级功能的信息
            PDAFunction parentfunctioninfo = pfunRep.Find(parentid);

            string addno = "";
            //查找上级功能下共有多少子功能
            int soncount = pfunRep.GetList<PDAFunction>().Where(m => m.ParentID == parentid).Count();
            if (soncount <=8)
            {
                soncount = soncount + 1;
                addno = "0" + soncount;
            }
            else
            {
                addno = (soncount + 1).ToString();
            }

            if (parentfunctioninfo != null)
            {
                string parentno = parentfunctioninfo.FunctionNo;
                pdafunction.FunctionNo = parentno + addno;
            }
            else
            {
                pdafunction.FunctionNo = "F" + addno;
            }

            try
            {
                pdafunction.CreateDate = DateTime.Now;
                pdafunction.OrderID = soncount + 1;
                pfunRep.Add(pdafunction);
                pfunRep.SaveChanges();
                return Json(new { Msg = "添加成功", IsSuccess = true });
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex.Message, ex);
                return Json(new { Msg = "出错了" });
            }
        }

        /// <summary>
        /// Delete user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter conditions</param>
        /// <returns></returns>
        public RedirectToRouteResult Delete(string id, int pageIndex, Searcher searcher)
        {
            try
            {
                var pda = dmRep.Find(id);
                dmRep.Delete(pda);
                dmRep.SaveChanges();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex.Message, ex);
            }
            return RedirectToAction("Grid", new { pageIndex = pageIndex, searcher = searcher });
        }

        /// <summary>
        /// Delete user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter conditions</param>
        /// <returns></returns>
        public RedirectToRouteResult Set(string id, int pageIndex, Searcher searcher)
        {
            try
            {
                var pda = dmRep.Find(id);
                pda.Status = 1;
                dmRep.Update(pda);
                dmRep.SaveChanges();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex.Message, ex);
            }
            return RedirectToAction("Grid", new { pageIndex = pageIndex, searcher = searcher });
        }

        /// <summary>
        /// Delete user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter conditions</param>
        /// <returns></returns>
        public RedirectToRouteResult Cancel(string id, int pageIndex, Searcher searcher)
        {
            try
            {
                var pda = dmRep.Find(id);
                pda.Status = 0;
                dmRep.Update(pda);
                dmRep.SaveChanges();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex.Message, ex);
            }
            return RedirectToAction("Grid", new { pageIndex = pageIndex, searcher = searcher });
        }

        [ActionName("Export")]
        [HttpPost]
        public JsonResult PreExport(Searcher searcher)
        {
            var pred = PDASpecification.Get_V_PDA_Pred(searcher);

            var list = dmRep.GetList<V_PDA>();
            bool hasdata = list.Where(pred).Count() > 0;
            return Json(new { searcher = searcher.ToString(), hasdata = hasdata });
        }


        /// <summary>
        /// Export dismachine report.
        /// </summary>
        /// <param name="searcher">Filter conditions.</param>
        /// <returns>Excel file.</returns>
        public void Export(Searcher searcher)
        {
            var pred = PDASpecification.Get_V_PDA_Pred(searcher);
            var list = dmRep.GetList<V_PDA>();

            var lst = list.Where(pred).OrderByDescending(d => d.CreateDate).ToList();

            string[] filters = new string[] {
                "PDANo","Status" ,"AccountName","CreateName","Purpose", "CreateDate"};

            var dt = lst.ToDataTable(filters);

            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    string status = dr["Status"] + "";
                    if (status == "1")
                    {
                        dr["Status"] = "已授权";
                    }
                    else
                    {
                        dr["Status"] = "未授权";
                    }
                }
            }
            string[] columnname = new string[] { "PDA编号","状态", "所属客户名称", "添加用户名称","用途", "添加日期"};

            ExcelHelper.ExportToExcel(null, "PDA报表", dt, columnname, filters, false);
        }


        /// <summary>
        /// Edit user.
        /// </summary>
        /// <param name="id">User id.</param>
        /// <param name="pageIndex">Page index.</param>
        /// <param name="searcher">Filter condtions.</param>
        /// <returns>User form.</returns>
        public ActionResult Config(string id)
        {
            TempData["PDAID"] = id;
            //得到该PDA的信息
            var pdainfo = dmRep.Find(id);
            string accountid = pdainfo.UsersID;

            var funcs = pufunRep.GetList<V_PDAUsersFunctions>().Where(m => m.UsersID == accountid).OrderBy(m=>m.OrderID).ToList(); //该PDA对应的客户所有的功能
            int count = 0;  //record menu action
            ConfigItem tree = new ConfigItem();
            tree.Items = new List<ConfigItem>();
            tree.Index = count++;
            tree.Text = "所有";
            tree.Parent = null;
            tree.Value = null;

            foreach (var item in funcs.Where(f => f.ParentPDAFunctionID == null || f.ParentPDAFunctionID == "0"))
            { //1级菜单
                ConfigItem onetemp = new ConfigItem
                {
                    Parent = null,
                    Index = count++,
                    Text = item.PDAFunctionName,
                    Value = item.PDAFunctionID,
                    Checked = pfunRep.IsPDAMatch(id, item.PDAFunctionID),
                };
                int oneIndex = 0;     //record actions exist in view
                tree.Items.Add(onetemp);

                if (funcs.Any(f => f.ParentPDAFunctionID == item.PDAFunctionID))
                {
                    onetemp.Items = new List<ConfigItem>();   //2级菜单
                    var funcTwo = funcs.Where(f => f.ParentPDAFunctionID == item.PDAFunctionID);

                    foreach (var two in funcTwo)
                    {
                        bool ischeck = pfunRep.IsPDAMatch(id, two.PDAFunctionID);
                        ConfigItem twotemp = new ConfigItem
                        {
                            Parent = onetemp,
                            Index = oneIndex++,
                            Text = two.PDAFunctionName,
                            Value = two.PDAFunctionID,
                            Checked = ischeck,
                        };
                        int twoIndex = 0;
                        onetemp.Items.Add(twotemp);

                        if (ischeck && (!onetemp.Checked || !tree.Checked))
                        {
                            //checked parent item if any of its children is checked
                            //when display the tree
                            if (!onetemp.Checked) { onetemp.Checked = true; }

                            if (!tree.Checked) { tree.Checked = true; }
                        }

                        twotemp.Items = new List<Models.ConfigItem>();//3级菜单
                        var functhree = funcs.Where(f => f.ParentPDAFunctionID == two.PDAFunctionID);

                        foreach (var three in functhree)
                        {
                            bool ischeckthree = pfunRep.IsPDAMatch(id, three.PDAFunctionID);
                            ConfigItem threetemp = new ConfigItem
                            {
                                Parent = twotemp,
                                Index = twoIndex++,
                                Text = three.PDAFunctionName,
                                Value = three.PDAFunctionID,
                                Checked = ischeckthree,
                            };

                            twotemp.Items.Add(threetemp);

                            if (ischeckthree && (!twotemp.Checked || !tree.Checked))
                            {
                                //checked parent item if any of its children is checked
                                //when display the tree
                                if (!twotemp.Checked) { twotemp.Checked = true; }

                                if (!tree.Checked) { tree.Checked = true; }
                            }

                            int threeIndex = 0;
                            threetemp.Items = new List<Models.ConfigItem>();//4级菜单
                            var funcfour = funcs.Where(f => f.ParentPDAFunctionID == three.PDAFunctionID);

                            foreach (var four in funcfour)
                            {
                                bool ischeckfour = pfunRep.IsPDAMatch(id, four.PDAFunctionID);
                                ConfigItem fourtemp = new ConfigItem
                                {
                                    Parent = threetemp,
                                    Index = threeIndex++,
                                    Text = four.PDAFunctionName,
                                    Value = four.PDAFunctionID,
                                    Checked = ischeckfour,
                                };

                                threetemp.Items.Add(fourtemp);

                                if (ischeckfour && (!threetemp.Checked || !tree.Checked))
                                {
                                    //checked parent item if any of its children is checked
                                    //when display the tree
                                    if (!threetemp.Checked) { threetemp.Checked = true; }

                                    if (!tree.Checked) { tree.Checked = true; }
                                }

                                int fourIndex = 0;
                                fourtemp.Items = new List<Models.ConfigItem>();//5级菜单
                                var funcfive = funcs.Where(f => f.ParentPDAFunctionID == four.PDAFunctionID);

                                foreach (var five in funcfive)
                                {
                                    bool ischeckfive = pfunRep.IsPDAMatch(id, five.PDAFunctionID);
                                    ConfigItem fivetemp = new ConfigItem
                                    {
                                        Parent = fourtemp,
                                        Index = fourIndex++,
                                        Text = five.PDAFunctionName,
                                        Value = five.PDAFunctionID,
                                        Checked = ischeckfive,
                                    };

                                    fourtemp.Items.Add(fivetemp);

                                    if (ischeckfive && (!fourtemp.Checked || !tree.Checked))
                                    {
                                        //checked parent item if any of its children is checked
                                        //when display the tree
                                        if (!fourtemp.Checked) { fourtemp.Checked = true; }

                                        if (!tree.Checked) { tree.Checked = true; }
                                    }
                                }
                            }

                        }
                    }
                }
            }
            return View(tree);
        }


        /// <summary>
        /// Config role functions.
        /// </summary>
        /// <param name="roleId">Role id.</param>
        /// <param name="TreeView1_checkedNodes">Checked nodes of function tree.</param>
        /// <returns>Role grid.</returns>
        [HttpPost]
        public ActionResult Config(string pdaid, List<ConfigItem> TreeView1_checkedNodes)
        {
            foreach (var viewItem in TreeView1_checkedNodes)
            {
                if (viewItem.Text != "所有")
                {
                    AddFunctionRole(pdaid, viewItem.Value, viewItem.Text, viewItem);
                }
            }
            return RedirectToAction("Index");
        }

        /// <summary>
        /// Add function to role.
        /// </summary>
        /// <param name="roleID">Role id.</param>
        /// <param name="functionID">Function id.</param>
        /// <param name="viewItem">Config item.</param>
        private void AddFunctionRole(string pdaid, string functionID, string functionName, ConfigItem viewItem)
        {
            var pdainfo = dmRep.Find(pdaid);
            string accountid = pdainfo.UsersID;

            if (viewItem.Checked == false)
            {  //delete menu item
                PDAPDAFunction frItem = ppfunRep.Find(f => f.PDAFunctionID == functionID && f.PDAID == pdaid);
                if (frItem != null)
                {
                    ppfunRep.Delete(frItem);
                    //view actions that is not display in menu
                    var viewaction = pufunRep.GetList<V_PDAUsersFunctions>().Where(m => m.UsersID == accountid && m.ParentPDAFunctionID == functionID).ToList();
                    if (viewaction != null && viewaction.Count() > 0)
                    {//view actions exists
                        foreach (var act in viewaction)
                        {
                            PDAPDAFunction childfunc = ppfunRep.Find(fr => fr.PDAID == pdaid && fr.PDAFunctionID == act.ID);
                            if (childfunc != null)
                            {
                                ppfunRep.Delete(childfunc); //delete view action
                            }
                        }
                    }
                    if (viewItem.Items != null && viewItem.Items.Count() > 0)
                    {
                        foreach (var Levelnd in viewItem.Items)
                        {
                            AddFunctionRole(pdaid, Levelnd.Value, Levelnd.Text, Levelnd);
                        }
                    }
                }
            }
            else
            {            //add menu item
                AddFunctionRole(pdaid, functionID, functionName);
                //view actions that is not display in menu
                var actions = pfunRep.All.Where(f => f.ParentID == functionID);
                if (actions != null && actions.Count() > 0)
                {
                    foreach (var act in actions)
                    {
                        AddFunctionRole(pdaid, act.ID, act.FunctionName);   //add view actions
                    }
                }
                if (viewItem.Items != null && viewItem.Items.Count() > 0)
                {
                    foreach (var Levelnd in viewItem.Items)
                    { //traversing its children
                        AddFunctionRole(pdaid, Levelnd.Value, Levelnd.Text, Levelnd);
                    }
                }
            }
            ppfunRep.SaveChanges();
        }

        /// <summary>
        /// Add function to role.
        /// </summary>
        /// <param name="roleID">Role id.</param>
        /// <param name="functionID">Function id.</param>
        private void AddFunctionRole(string pdaid, string functionID, string functionName)
        {
            PDAPDAFunction frItem = ppfunRep.Find(f => f.PDAFunctionID == functionID && f.PDAID == pdaid);
            if (frItem == null)
            {  //add function if no exist in database
                frItem = new PDAPDAFunction
                {
                    ID = Guid.NewGuid().ToString(),
                    PDAFunctionID = functionID,
                    PDAFunctionName = functionName,
                    PDAID = pdaid,
                    CreateDate = DateTime.Now
                };
                ppfunRep.Add(frItem);
            }
            ppfunRep.SaveChanges();
        }
    }
}
